package com.zzyl.nursing.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.zzyl.common.exception.ServiceException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.CheckInConfig;
import com.zzyl.nursing.domain.Contract;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInContractDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import com.zzyl.utils.CodeGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.domain.CheckIn;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * inService业务层处理
 * 
 * @author lhs
 * @date 2025-05-23
 */
@Service
@Slf4j
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;
    /**
     * 查询in
     * 
     * @param id in主键
     * @return in
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询in列表
     * 
     * @param checkIn in
     * @return in
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增in
     * 
     * @param checkIn in
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改in
     * 
     * @param checkIn in
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除in
     * 
     * @param ids 需要删除的in主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除in信息
     * 
     * @param id in主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(CheckInApplyDto checkInApplyDto) {
        log.info("入住办理：{}", checkInApplyDto);
        //检验老人是否已经入住（判断，对就下一步，错就报错）
        //1、先获取老人传进来的信息
        CheckInElderDto checkInElderDto = checkInApplyDto.getCheckInElderDto();
        //获取入住信息身份证与需要办理入住的用户身份证一样的用户信息
        Elder elder = elderMapper.selectOne
                (new LambdaQueryWrapper<Elder>()
                        .eq(Elder::getIdCardNo, checkInElderDto.getIdCardNo())); //等级过的老人信息
        log.info("数据库中的老人信息: {}", elder);
        if (elder != null) {//证明登记过
            if(elder.getStatus() == 1 ||  elder.getStatus() == 2 || elder.getStatus() == 4){
                throw new ServiceException("该用户已入住");
            }
        }//否则没有入住
        //1、获取他选择的床位号
        Long bedId = checkInApplyDto.getCheckInConfigDto().getBedId();
        //设置更新床位的状态为1，且返回更新的条数
       int status = bedMapper.updateBedStatus(bedId);
       if (status == 0) {//如果返回的更新条数为0，没有更新成功，该床位已入住
           throw new ServiceException("该床位已入住");
       }
        //否则更新床位为已入住
        //新增或者更新老人
        //1、保存数据到pojo中去
       Elder elders =   extracted(checkInApplyDto, bedId, elder);
        //新增签约办理
        contract(checkInApplyDto, elders);
        //新增入住信息
        CheckIn checkIn = addCheckIn(checkInApplyDto, elders);//虽然不是接收的对象，但是要保存数据库，因为列表保存需要
        //新增入住配置
        checkInFig(checkInApplyDto, checkIn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CheckInDetailVo detail(Integer id) {
        CheckInDetailVo vo = new CheckInDetailVo();
        //查询入住信息    check_in表
        CheckIn checkIn = checkInMapper.selectById(id);
        //查询老人信息    elder表
        Elder elder = elderMapper.selectById(checkIn.getElderId());
        if(elder == null){
         throw   new ServiceException("该用户不存在");
        }
        int age = calculateAge(elder.getIdCardNo());
        vo.setCheckInElderVo(BeanUtil.toBean(elder, CheckInElderVo.class));
        vo.getCheckInElderVo().setAge(age);
        //添加家属
        List<ElderFamilyVo> list = JSONUtil.toList(checkIn.getRemark(),  ElderFamilyVo.class);
        vo.setElderFamilyVoList(list);

        //查询合同       contract表
        Contract contract = contractMapper.selectOne(new LambdaQueryWrapper<Contract>()
                .eq( Contract::getElderId,elder.getId()));
        //查询入住配置    check_in_config表
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(new LambdaQueryWrapper<CheckInConfig>()
                .eq(CheckInConfig::getCheckInId, checkIn.getId()));

        vo.setContract(contract);
        vo.setCheckInConfigVo(BeanUtil.toBean(checkInConfig, CheckInConfigVo.class));
        //1、补充时间
        vo.getCheckInConfigVo().setStartDate(checkIn.getStartDate());
        vo.getCheckInConfigVo().setEndDate(checkIn.getEndDate());


        return vo;
    }

    //
    public static int calculateAge(String idCard) {
        String birthDateStr = idCard.substring(6, 14); // 提取出生日期部分
        int year = Integer.parseInt(birthDateStr.substring(0, 4));
        int month = Integer.parseInt(birthDateStr.substring(4, 6));
        int day = Integer.parseInt(birthDateStr.substring(6, 8));

        LocalDate birthDate = LocalDate.of(year, month, day);
        LocalDate currentDate = LocalDate.now();

        return Period.between(birthDate, currentDate).getYears();
    }


    private void checkInFig(CheckInApplyDto checkInApplyDto, CheckIn checkIn) {
        CheckInConfig checkInConfig = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckInConfig.class);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);
        log.info("新增入住配置信息: id={}", checkInConfig.getId());
    }

    private CheckIn addCheckIn(CheckInApplyDto checkInApplyDto, Elder bean) {
        CheckIn checkIn = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckIn.class);
        checkIn.setElderId(bean.getId());
        checkIn.setElderName(bean.getName());
        checkIn.setIdCardNo(checkInApplyDto.getCheckInElderDto().getIdCardNo());
        checkIn.setBedNumber(bean.getBedNumber());
        checkIn.setStatus(0);//已入住
        // 紧急联系人
        checkIn.setRemark(JSON.toJSONString(checkInApplyDto.getElderFamilyDtoList()));
        save(checkIn);
        log.info("新增入住信息: id={}", checkIn.getId());
        return checkIn;
    }

    private void contract(CheckInApplyDto checkInApplyDto, Elder bean) {
        //1、获取前端传递的签约办理信息
        CheckInContractDto checkInContractDto = checkInApplyDto.getCheckInContractDto();
        //2、把他拷贝到pojo类中
        Contract contract = BeanUtil.toBean(checkInContractDto, Contract.class);
        //3、补全信息
        //3.1、老人名字
        contract.setElderName(bean.getName());
        //3.2、老人id
        contract.setElderId(bean.getId().intValue());
        //3.3、合同开始时间与结束时间
        LocalDateTime startData= checkInApplyDto.getCheckInConfigDto().getStartDate();
        LocalDateTime endData= checkInApplyDto.getCheckInConfigDto().getEndDate();
        contract.setStartDate(startData);
        contract.setEndDate(endData);
        //3.4、当前时间与合同时间作比较
        if(startData.isBefore(LocalDateTime.now())){
            //如果开始时间小于系统时间说明已经开始了
            contract.setStatus(1);
        }else if (startData.isAfter(LocalDateTime.now())){
            //如果开始时间大于系统时间说明还没有开始
            contract.setStatus(0);
        } else if (endData.isBefore(LocalDateTime.now())){
         throw new ServiceException("结束日期要大于当前系统时间");
        }
        //生成一个合同编号
        contract.setContractNumber(CodeGenerator.generateContractNumber());
        //保存到数据库
        contractMapper.insert(contract);
        log.info("合同新增成功，id={}",contract.getId());
    }

    private Elder extracted(CheckInApplyDto checkInApplyDto, Long bedId, Elder elder) {
        Elder bean = BeanUtil.toBean(checkInApplyDto.getCheckInElderDto(), Elder.class);//创建一个pojo类并且把数据塞进去
        bean.setStatus(1);
        bean.setBedId(bedId);
        bean.setBedNumber(bedMapper.selectById(bedId).getBedNumber());//通过床位id获得床位信息再获取床位编号
        //判断是为新增或者更新老人（存在是更新，不存在是新增）
        if(elder != null){

            //设置老人的id等于之前的id
            bean.setId(elder.getId());
            //更新老人信息
            elderMapper.updateById(bean);
        }else{
            elderMapper.insert(bean);
            log.info("新增老人信息成功,id={}", bean.getId());
        }
        return bean;
    }
}
